#ifndef SOLUTION_H_
#define SOLUTION_H_

#include <iostream>
#include <ostream>
#include <vector>
#include "../Random/MyRandom.h"
#include "SolutionFactory.h"
using namespace std;

/** Base class for different solution encodings.
 */
class Solution
{
	public:
		Solution();
		virtual ~Solution();
        virtual Solution* clone() = 0;                  /**< Returns a pointer to a copy of the object */
		float getFitness() const;                       /**< Returns the current solution fitness      */
		void setFitness(float);                         /**< Sets the solution fitness                 */	
		virtual void mutate() = 0;                      /**< Mutates the solution                      */
		static void setMutationRate(float);             /**< Sets the mutation rate for solutions      */
		static float getMutationRate();		            /**< Returns the current mutation rate         */
        virtual ostream& outputSolution(ostream &) = 0; /**< Abstract output solution function         */
        virtual SolutionType getSerializationIdentifyer();       /**< Returns the serialization identifyer used by the solution factory */
        
	protected:
		float fitness;                                  /**< The fitness of the solution               */
		static float mutationRate;                      /**< The mutation rate for all solutions       */
};

//TODO: instead of this operation knowing how to format a solution pointer,
//should it instead know how to format a solution and we de-reference
//the pointer everywhere that we use this operator?
//i.e.
//   Solution* ptr;
//   cout << ptr << endl;
//
//   vs
//
//   Solution* ptr;
//   cout << *ptr << endl;
static ostream &operator<<(ostream &output, Solution* &sol) 
{
    return sol->outputSolution(output);
}

#endif /*SOLUTION_H_*/
